{T}

程序员练级攻略:软件设计-[2026重制版]

核心变更说明:本文基于2018年版全面升级,新增SOLID原则的2026实践、设计模式的正确使用指南、架构模式(六边形/整洁/CQRS)、DDD领域驱动设计入门、API设计最佳实践(OpenAPI 3.1)、以及反模式和代码坏味道的识别与重构。

软件设计能力是每个程序员都需要具备的基本素质。这里描述了软件工程自发展以来的各种设计方法,这是从工程师通往架构师的必备技能。

🎯 为什么软件设计如此重要?

图表渲染中…

设计 vs 不设计的区别

维度有设计无设计
开发初期稍慢(需要思考)快速(直接写)
中期迭代平稳开始变慢
后期维护高效极其痛苦
新人上手容易困难
Bug率

📐 SOLID设计原则

S - 单一职责原则 (Single Responsibility Principle)

一个类应该只有一个引起它变化的原因

java
// ❌ 违反SRP:User类承担了太多职责
public class User {
    private String name;
    private String email;
 
    public void saveToDatabase() { /* ... */ }
    public void sendEmail() { /* ... */ }
    public void generateReport() { /* ... */ }
    public void validateInput() { /* ... */ }
}
 
// ✅ 遵循SRP:每个类只有一个职责
public class User { // 只负责数据
    private final String name;
    private final String email;
    // getters...
}
 
public class UserRepository { // 只负责持久化
    public void save(User user) { /* ... */ }
}
 
public class EmailService { // 只负责邮件
    public void sendWelcomeEmail(User user) { /* ... */ }
}

O - 开闭原则 (Open-Closed Principle)

对扩展开放,对修改关闭

java
// ❌ 违反OCP:每次新增折扣类型都要修改原类
public class DiscountCalculator {
    public double calculateDiscount(String type, double price) {
        switch (type) {
            case "STUDENT": return price * 0.8;
            case "SENIOR": return price * 0.85;
            case "VIP": return price * 0.7;
            default: return price;
        }
    }
}
 
// ✅ 遵循OCP:通过扩展而非修改
public interface DiscountStrategy {
    double calculate(double originalPrice);
}
 
record StudentDiscount() implements DiscountStrategy {
    public double calculate(double price) { return price * 0.8; }
}
 
record VipDiscount() implements DiscountStrategy {
    public double calculate(double price) { return price * 0.7; }
}
 
// 新增折扣类型只需实现接口,无需修改现有代码
class NewYearDiscount implements DiscountStrategy {
    public double calculate(double price) { return price * 0.65; }
}

L - 里氏替换原则 (Liskov Substitution Principle)

子类型必须能够替换其基类型

java
// ❌ 违反LSP:正方形不能替换长方形
class Rectangle {
    protected int width, height;
    public void setWidth(int w) { this.width = w; }
    public void setHeight(int h) { this.height = h; }
    public int getArea() { return width * height; }
}
 
class Square extends Rectangle {
    @Override
    public void setWidth(int w) {
        super.setWidth(w);
        super.setHeight(w);  // 正方形宽高必须相等!
    }
    @Override
    public void setHeight(int h) {
        super.setHeight(h);
        super.setWidth(h);
    }
}
 
// 使用Rectangle的地方传入Square会出问题!
void test(Rectangle r) {
    r.setWidth(5);
    r.setHeight(10);  // 如果r是Square,宽度也被改成10了!
    assert r.getArea() == 50;  // 失败!实际面积100
}

I - 接口隔离原则 (Interface Segregation Principle)

客户端不应该被迫依赖它不使用的方法

java
// ❌ 违反ISP:大而全的接口
interface Worker {
    void work();
    void eat();
    void code();
    void test();
    void manage();
}
 
// ✅ 遵循ISP:小而精的接口
interface Workable {
    void work();
}
 
interface Feedable {
    void eat();
}
 
interface Codeable {
    void code();
}
 
class Developer implements Workable, Feedable, Codeable {
    public void work() { /* ... */ }
    public void eat() { /* ... */ }
    public void code() { /* ... */ }
}
 
class Robot implements Workable, Codeable {
    public void work() { /* ... */ }
    public void code() { /* ... */ }
    // Robot不需要eat()
}

D - 依赖倒置原则 (Dependency Inversion Principle)

依赖抽象,不依赖具体

图表渲染中…

🏗️ 经典设计模式(GoF 23种)

创建型模式

模式场景2026应用示例
单例模式全局唯一实例数据库连接池、配置管理器
工厂方法对象创建逻辑复杂Spring BeanFactory
抽象工厂产品族创建UI主题切换、数据库适配器
建造者模式复杂对象构建HTTP请求构建器、SQL查询构建器
原型模式对象克隆深拷贝对象图

结构型模式

模式场景2026应用示例
适配器模式接口兼容日志框架适配、第三方SDK封装
装饰器模式动态增强功能Java I/O流、Spring AOP代理
代理模式控制对象访问MyBatis Mapper、RPC Stub
外观模式简化子系统API Gateway、Facade Service
组合模式树形结构DOM树、UI组件树、文件系统
享元模式细粒度共享字符串常量池、线程池

行为型模式

模式场景2026应用示例
策略模式算法可替换支付方式选择、排序策略
观察者模式事件通知EventBus、消息队列消费者
模板方法算法骨架固定AbstractTemplateClass
命令模式操作封装事务操作、撤销重做
状态模式状态机订单状态流转、TCP连接状态
责任链模式请求处理链Filter Chain、中间件管道
迭代器模式集合遍历Java Collection Iterator
备忘录模式状态快照撤销操作、游戏存档
中介者模式解耦交互聊天室、MVC Controller
访问者模式操作分离编译器AST遍历、报表生成

重要提醒

不要迷失在23个设计模式中! 你一定要明白两个原则:

  1. Program to an 'Interface', not an 'Implementation'
  2. Favor 'object composition' over 'class inheritance'

📊 设计模式使用频率(2026)

图表渲染中…

🏛️ 架构模式(2026新增)

分层架构 (Layered Architecture)

图表渲染中…

六边形架构 / 端口适配器架构

图表渲染中…

CQRS (Command Query Responsibility Segregation)

适用于读写差异大的系统:

图表渲染中…

🔧 重构与代码坏味道

常见代码坏味道 (Code Smells)

坏味道表现解决方案
重复代码 (Duplicated Code)相似代码出现在多处提取方法/类
过长方法 (Long Method)方法超过50行提取方法
大类 (Large Class)类超过500行拆分职责
过长参数列表 (Long Parameter List)参数超过5个使用参数对象/Builder
发散变化 (Divergent Change)一个类因不同原因变化拆分成多个类
霰弹修改 (Shotgun Surgery)改一个功能要改很多类Move Method/Field
特性依恋 (Feature Envy)方法更关心其他类的数据Move Method
数据泥团 (Data Clumps)总是一起出现的数据字段提取为类
基本类型偏执 (Primitive Obsession)用基本类型表示领域概念使用值对象
switch语句泛滥大量switch/if-else多态/策略模式

重构技巧(部分)

技巧说明
Extract Method将一段代码提取为独立方法
Extract Class将部分职责提取为新类
Move Method/Field移动方法或字段到合适的类
Replace Conditional with Polymorphism用多态替代条件语句
Introduce Parameter Object将长参数列表合并为对象
Replace Magic Number with Symbolic Constant用常量替代魔法数字
Decompose Conditional复杂条件拆分为独立方法

📚 推荐资源

必读书籍

书名作者核心价值
《设计模式:可复用面向对象软件的基础》 (GoF)Gang of Four23种经典设计模式
《Head First设计模式》Eric Freeman图文并茂易理解
《重构:改善既有代码的设计》Martin Fowler系统化重构方法论
《敏捷软件开发:原则、模式与实践》Robert C. MartinSOLID原则详解
《企业应用架构模式》Martin Fowler企业级架构模式
《实现领域驱动设计》Vaughn VernonDDD实战指导
《整洁架构》Robert C. Martin架构设计原则

在线资源

资源网址特点
Refactoring Guruhttps://refactoring.guru/design-patterns图解设计模式,非常直观
Source Makinghttps://sourcemaking.com/模式和原则全面
Design Patterns Libraryhttps://www.dofactory.com/net/design-patterns示例代码丰富

下一篇文章我们将进入高手成长篇的第一章:Linux系统、内存和网络——深入系统底层的知识。